package game.cube;

public class Matrix {
	public float[] m;
	public float   mAngleX;
	public float   mAngleY;
	public float   mAngleZ;
	public final float RADIAN = 3.14159265358f / 180.0f;

	public Matrix() {
		m = new float[16];
		identity();
		mAngleX = 0.0f;
		mAngleY = 0.0f;
		mAngleZ = 0.0f;

	}

	public void identity() {
		for (int i = 0; i < 16; ++i) {
			if (i % 5 == 0) {
				m[i] = 1.0f;
			} else {
				m[i] = 0.0f;
			}
		}
	}

	public float[] multiple_vector(float x, float y, float z) {
		float[] ret = new float[3];

		ret[0] = m[0] * x + m[1] * y + m[2] * z + m[3];
		ret[1] = m[4] * x + m[5] * y + m[6] * z + m[7];
		ret[2] = m[8] * x + m[9] * y + m[10] * z + m[11];

		return ret;
	}
	public Matrix multiple_matrix(Matrix matrix) {
		Matrix ret = new Matrix();
		for (int i = 0; i < 4; ++i) {
			for (int j = 0; j < 4; ++j) {
				ret.m[i * 4 + j] =
						m[j * 4 + 0] * matrix.m[0 + i] +
						m[j * 4 + 1] * matrix.m[4 + i] +
						m[j * 4 + 2] * matrix.m[8 + i] +
						m[j * 4 + 3] * matrix.m[12+ i];
			}
		}
		return ret;
	}

	public void set_translate(float x, float y, float z) {
		m[3] = x;
		m[7] = y;
		m[11] = z;
	}

	public void set_inverse_translate(float x, float y, float z) {
		m[12] = x;
		m[13] = y;
		m[14] = z;
	}

	public void add_translate(float x, float y, float z) {
		m[3] += x;
		m[7] += y;
		m[11] += z;
	}

	public void add_inverse_translate(float x, float y, float z) {
		m[12] += x;
		m[13] += y;
		m[14] += z;
	}


	public void set_rotate_x(float angle) {
		double temp = angle * RADIAN;
		m[0] = 1.0f;	m[4] =  0.0f;					m[8] = 0.0f;					m[12] = 0.0f;
		m[1] = 0.0f;	m[5] =  (float)Math.cos(temp);	m[9] = (float)Math.sin(temp);	m[13] = 0.0f;
		m[2] = 0.0f;	m[6] = -(float)Math.sin(temp);	m[10] = (float)Math.cos(temp);	m[14] = 0.0f;
		m[3] = 0.0f;	m[7] =  0.0f;					m[11] = 0.0f;					m[15] = 1.0f;
	}

	public void add_rotate_x(float angle) {
		mAngleX += angle;
		if (mAngleX >= 360.0f) {
			mAngleX = 0;
		}
		double temp = mAngleX * RADIAN;
		m[0] = 1.0f;	m[4] =  0.0f;					m[8] = 0.0f;					m[12] = 0.0f;
		m[1] = 0.0f;	m[5] =  (float)Math.cos(temp);	m[9] = (float)Math.sin(temp);	m[13] = 0.0f;
		m[2] = 0.0f;	m[6] = -(float)Math.sin(temp);	m[10] = (float)Math.cos(temp);	m[14] = 0.0f;
		m[3] = 0.0f;	m[7] =  0.0f;					m[11] = 0.0f;					m[15] = 1.0f;
	}

	public void set_rotate_y(float angle) {
		double temp = angle * RADIAN;
		m[0] = (float)Math.cos(temp);	m[4] = 0.0f;	m[8] = -(float)Math.sin(temp);	m[12] = 0.0f;
		m[1] = 0.0f;					m[5] = 1.0f;	m[9] = 0.0f;					m[13] = 0.0f;
		m[2] = (float)Math.sin(temp);	m[6] = 0.0f;	m[10] = (float)Math.cos(temp);	m[14] = 0.0f;
		m[3] = 0.0f;					m[7] = 0.0f;	m[11] = 0.0f;					m[15] = 1.0f;
	}

	public void add_rotate_y(float angle) {
		mAngleY += angle;
		if (mAngleY >= 360.0f) {
			mAngleY = 0;
		}
		double temp = mAngleY * RADIAN;
		m[0] = (float)Math.cos(temp);	m[4] = 0.0f;	m[8] = -(float)Math.sin(temp);	m[12] = 0.0f;
		m[1] = 0.0f;					m[5] = 1.0f;	m[9] = 0.0f;					m[13] = 0.0f;
		m[2] = (float)Math.sin(temp);	m[6] = 0.0f;	m[10] = (float)Math.cos(temp);	m[14] = 0.0f;
		m[3] = 0.0f;					m[7] = 0.0f;	m[11] = 0.0f;					m[15] = 1.0f;
	}

	public void set_rotate_z(float angle) {
		double temp = angle * RADIAN;
		m[0] =  (float)Math.cos(temp);	m[4] = (float)Math.sin(temp);	m[8] = 0.0f;	m[12] = 0.0f;
		m[1] = -(float)Math.sin(temp);	m[5] = (float)Math.cos(temp);	m[9] = 0.0f;	m[13] = 0.0f;
		m[2] = 0.0f;                  	m[6] = 0.0f;					m[10] = 1.0f;	m[14] = 0.0f;
		m[3] = 0.0f;					m[7] = 0.0f;					m[11] = 0.0f;	m[15] = 1.0f;
	}

	public void add_rotate_z(float angle) {
		mAngleZ += angle;
		if (mAngleZ >= 360.0f) {
			mAngleZ = 0;
		}
		double temp = mAngleZ * RADIAN;
		m[0] =  (float)Math.cos(temp);	m[4] = (float)Math.sin(temp);	m[8] = 0.0f;	m[12] = 0.0f;
		m[1] = -(float)Math.sin(temp);	m[5] = (float)Math.cos(temp);	m[9] = 0.0f;	m[13] = 0.0f;
		m[2] = 0.0f;                  	m[6] = 0.0f;					m[10] = 1.0f;	m[14] = 0.0f;
		m[3] = 0.0f;					m[7] = 0.0f;					m[11] = 0.0f;	m[15] = 1.0f;
	}
}
